package com.gotye.particlesystem.objects;

import android.opengl.GLES20;

import com.gotye.particlesystem.data.VertexArray;
import com.gotye.particlesystem.programs.ColorShaderProgram;

import java.nio.ByteBuffer;
import java.util.ArrayList;

/**
 * Created by Michael.Ma on 2016/6/29.
 */
public class Ball {
    private int vCount = 0; // vertex
    private int iCount = 0; // index
    private ByteBuffer indexArray; //顶点构建索引数据缓冲

    private VertexArray vertexArray;
    private VertexArray normalArray; //顶点法向量数据缓冲

    private boolean bLineFrame = false;

    private static final float UNIT_SIZE = 1.0f;// 单位尺寸
    private float radius = 1f; // 球的半径
    final int angleSpan = 18;// 将球进行单位切分的角度

    private static final int POSITION_COMPONENT_COUNT = 3;
    private static final int TEXTURE_COORDINATES_COMPONENT_COUNT = 2;
    private static final int BYTES_PER_FLOAT = 4;
    private static final int STRIDE =
            (POSITION_COMPONENT_COUNT + TEXTURE_COORDINATES_COMPONENT_COUNT) * BYTES_PER_FLOAT;

    public Ball(float r) {
        this.radius = r;

        initVertexData(r);
    }

    private void initVertexData(float scale) {
        ArrayList<Float> alVertex = new ArrayList<>();
        for (int vAngle = -90; vAngle <= 90; vAngle=vAngle+angleSpan) {  //垂直方向angleSpan度一份
            for (int hAngle = 0; hAngle <360; hAngle=hAngle+angleSpan ) { //水平方向angleSpan度一份
                //纵向横向各到一个角度后计算对应的此点在球面上的坐标
                double xozLength = scale * UNIT_SIZE * Math.cos(Math.toRadians(vAngle));
                float x = (float) (xozLength * Math.cos(Math.toRadians(hAngle)));
                float y = (float) (xozLength * Math.sin(Math.toRadians(hAngle))) ;
                float z = (float) (scale * UNIT_SIZE * Math.sin(Math.toRadians(vAngle)));
                alVertex.add(x);
                alVertex.add(y);
                alVertex.add(z);
            }
        }
        vCount = alVertex.size()/3;  //顶点数量为坐标值数量的三分之一，因为一个顶点有三个坐标
        //将alVertix中的坐标值转存到一个int数组中
        float vertices [] = new float[alVertex.size()];
        for (int i = 0; i < alVertex.size(); i++) {
            vertices[i]=alVertex.get(i);
        }

        vertexArray = new VertexArray(vertices);
        normalArray = new VertexArray(vertices);

        ArrayList<Integer> alIndex= new ArrayList<>();
        int row = (180/angleSpan) + 1; //球面切分的行数
        int col = 360/angleSpan;  //球面切分的列数
        for (int i = 0; i < row; i++) {  //对每一行循环
            if(i>0 && i<row-1){
                //中间行
                for (int j = -1; j < col; j++) {
                    //中间行的两个相邻点与下一行的对应点构成三角形
                    int k=i*col+j;
                    alIndex.add(k+col);
                    alIndex.add(k+1);
                    alIndex.add(k);
                }
                for (int j = 0; j < col+1; j++) {
                    //中间行的两个相邻点与上一行的对应点构成三角形
                    int k=i*col+j;
                    alIndex.add(k-col);
                    alIndex.add(k-1);
                    alIndex.add(k);
                }
            }
        }
        iCount = alIndex.size();
        byte indices []=new byte[iCount];
        for (int i = 0; i < iCount; i++) {
            indices[i]=alIndex.get(i).byteValue();
        }
        //三角形构造数据索引缓冲
        indexArray = ByteBuffer.allocateDirect(iCount);  //由于indices是byte型的，索引不用乘以4
        indexArray.put(indices);
        indexArray.position(0);
    }

    public void bindData(ColorShaderProgram colorShaderProgram) {
        vertexArray.setVertexAttribPointer(
                0,
                colorShaderProgram.getPositionAttributeLocation(),
                POSITION_COMPONENT_COUNT,
                /*STRIDE*/0);
    }

    public void setLineFrame(boolean ON) {
        this.bLineFrame = ON;
    }

    public void draw() {
        GLES20.glDrawElements(
                bLineFrame ? GLES20.GL_LINE_STRIP : GLES20.GL_TRIANGLES,
                iCount, GLES20.GL_UNSIGNED_BYTE,
                indexArray);
    }
}
